home *** CD-ROM | disk | FTP | other *** search
/ Aminet 30 / Aminet 30 (1999)(Schatztruhe)[!][Apr 1999].iso / Aminet / dev / lang / SmallEiffel.lha / SmallEiffel / lib_se / run_feature.e < prev    next >
Text File  |  1998-12-22  |  27KB  |  1,135 lines

  1. --          This file is part of SmallEiffel The GNU Eiffel Compiler.
  2. --          Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
  3. --            Dominique COLNET and Suzanne COLLIN - colnet@loria.fr 
  4. --                       http://www.loria.fr/SmallEiffel
  5. -- SmallEiffel is  free  software;  you can  redistribute it and/or modify it 
  6. -- under the terms of the GNU General Public License as published by the Free
  7. -- Software  Foundation;  either  version  2, or (at your option)  any  later 
  8. -- version. SmallEiffel is distributed in the hope that it will be useful,but
  9. -- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. -- or  FITNESS FOR A PARTICULAR PURPOSE.   See the GNU General Public License 
  11. -- for  more  details.  You  should  have  received a copy of the GNU General 
  12. -- Public  License  along  with  SmallEiffel;  see the file COPYING.  If not,
  13. -- write to the  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  14. -- Boston, MA 02111-1307, USA.
  15. --
  16. deferred class RUN_FEATURE
  17.    --
  18.    -- A feature at run time : assertions collected and only run types.
  19.    --
  20.    --   RUN_FEATURE_1  : constant attribute.
  21.    --   RUN_FEATURE_2  : attribute.
  22.    --   RUN_FEATURE_3  : procedure.
  23.    --   RUN_FEATURE_4  : function.
  24.    --   RUN_FEATURE_5  : once procedure.
  25.    --   RUN_FEATURE_6  : once function.
  26.    --   RUN_FEATURE_7  : external procedure.
  27.    --   RUN_FEATURE_8  : external function.
  28.    --   RUN_FEATURE_9  : deferred routine.
  29.    --   RUN_FEATURE_10 : Precursor procedure.
  30.    --   RUN_FEATURE_11 : Precursor function.
  31.    --
  32.    
  33. inherit GLOBALS;
  34.    
  35. feature 
  36.    
  37.    current_type: TYPE;
  38.      -- The type of Current in the corresponding feature.
  39.  
  40.    clients_memory: CLIENT_LIST;
  41.  
  42. feature {NONE}
  43.    
  44.    actuals_clients: FIXED_ARRAY[RUN_CLASS];
  45.      -- Places of callers.
  46.    
  47. feature 
  48.    
  49.    name: FEATURE_NAME;
  50.      -- Final name (the only one really used) of the feature.
  51.    
  52.    base_feature: E_FEATURE;
  53.      -- Original base feature definition.
  54.    
  55.    arguments: FORMAL_ARG_LIST is
  56.      -- Runnable arguments list if any.
  57.       deferred
  58.       end;
  59.  
  60.    result_type: TYPE is
  61.      -- Runnable Result type if any.
  62.       deferred
  63.       end;
  64.    
  65.    require_assertion: RUN_REQUIRE;
  66.      -- Runnable collected require assertion if any.
  67.    
  68.    local_vars: LOCAL_VAR_LIST is
  69.      -- Runnable local var list if any.
  70.       deferred
  71.       end;
  72.    
  73.    routine_body: COMPOUND is
  74.      -- Runnable routine body if any.
  75.       deferred
  76.       end;
  77.  
  78.    ensure_assertion: E_ENSURE;
  79.      -- Runnable collected ensure assertion if any.
  80.    
  81.    rescue_compound: COMPOUND is
  82.      -- Runnable rescue compound if any.
  83.       deferred
  84.       end;
  85.  
  86.    is_once_function: BOOLEAN is
  87.       deferred
  88.       end;
  89.  
  90. feature {NONE}        
  91.    
  92.    frozen make(t: like current_type; n: like name; bf: like base_feature) is
  93.       require
  94.      t.run_type = t;
  95.      n /= Void;
  96.      bf /= void;
  97.      not small_eiffel.is_ready
  98.       do
  99.      current_type := t; 
  100.      name := n; 
  101.      base_feature := bf; 
  102.      run_class.add_rf(Current,n.to_key);
  103.      small_eiffel.incr_magic_count;
  104.      use_current_state := ucs_not_computed;
  105.      small_eiffel.push(Current);
  106.      initialize;
  107.      small_eiffel.pop;
  108.       ensure
  109.      run_class.get_feature(name) = Current
  110.       end;
  111.    
  112. feature 
  113.    
  114.    is_pre_computable: BOOLEAN is
  115.       require
  116.      small_eiffel.is_ready
  117.       deferred
  118.       end;
  119.    
  120.    can_be_dropped: BOOLEAN is
  121.       -- If calling has no side effect at all.
  122.       require
  123.      small_eiffel.is_ready
  124.       deferred
  125.       end;
  126.    
  127.    frozen use_current: BOOLEAN is
  128.       require
  129.      small_eiffel.is_ready
  130.       do
  131.      inspect
  132.         use_current_state 
  133.      when ucs_true then
  134.         Result := true;
  135.      when ucs_false then
  136.      when ucs_not_computed then
  137.         use_current_state := ucs_in_computation;
  138.         compute_use_current;
  139.         Result := use_current; 
  140.      when ucs_in_computation then
  141.         Result := true;
  142.      end;
  143.       end;
  144.  
  145.    frozen fall_down is
  146.       local
  147.      running: ARRAY[RUN_CLASS];
  148.      i: INTEGER;
  149.      current_rc, sub_rc: RUN_CLASS;
  150.      current_bc, sub_bc: BASE_CLASS;
  151.      sub_name: FEATURE_NAME;
  152.      rf: RUN_FEATURE;
  153.       do
  154.      current_rc := current_type.run_class;
  155.      running := current_rc.running;
  156.      if running /= Void then
  157.         from  
  158.            current_bc := current_type.base_class;
  159.            i := running.lower;
  160.         until
  161.            i > running.upper
  162.         loop
  163.            sub_rc := running.item(i);
  164.            if sub_rc /= current_rc then
  165.           sub_bc := sub_rc.current_type.base_class;
  166.           sub_name := sub_bc.new_name_of(current_bc,name);
  167.           rf := sub_rc.get_feature(sub_name);
  168.            end;
  169.            i := i + 1;
  170.         end;
  171.      end;
  172.       end;
  173.  
  174.    afd_check is
  175.       deferred
  176.       end;
  177.          
  178.    is_exported_in(cn: CLASS_NAME): BOOLEAN is
  179.      -- True if using of the receiver is legal when written in `cn'.
  180.      -- When false, `eh' is updated with the beginning of the 
  181.      -- error message.
  182.       require
  183.      cn /= Void
  184.       do
  185.      Result := clients.gives_permission_to(cn);
  186.       end;
  187.       
  188.    frozen start_position: POSITION is
  189.       do
  190.      Result := base_feature.start_position;
  191.       end;
  192.  
  193.    frozen run_class: RUN_CLASS is
  194.       do
  195.      Result := current_type.run_class;
  196.       end;
  197.    
  198. feature {NONE}
  199.  
  200.    clients: like clients_memory is 
  201.      -- Effective client list for the receiver. 
  202.      -- Note: consider "export" clauses.
  203.       local
  204.      bc, bfbc: BASE_CLASS;
  205.       do
  206.      if clients_memory = Void then
  207.         bc := current_type.base_class;
  208.         bfbc := base_feature.base_class;
  209.         if bc = bfbc then
  210.            Result := base_feature.clients;
  211.         else
  212.            check
  213.           bc.is_subclass_of(bfbc)
  214.            end;
  215.            Result := bc.clients_for(name);
  216.         end;
  217.         clients_memory := Result;
  218.      else
  219.         Result := clients_memory;
  220.      end;
  221.       ensure
  222.      Result /= Void
  223.       end;
  224.    
  225. feature {RUN_CLASS,CREATION_CALL}
  226.  
  227.    add_client(rc: RUN_CLASS) is
  228.      -- Add `rc' to `actual_clients'.
  229.      -- Note: DO NOT check that `rc' is allowed to use it.
  230.       require
  231.      rc /= Void
  232.       local
  233.      i: INTEGER;
  234.       do
  235.      if actuals_clients = Void then
  236.         !!actuals_clients.with_capacity(4);
  237.         actuals_clients.add_last(rc);
  238.      else
  239.         i := actuals_clients.fast_index_of(rc);
  240.         if i > actuals_clients.upper then
  241.            actuals_clients.add_last(rc);
  242.         end;
  243.      end;
  244.      run_class.add_client(rc);
  245.       end;
  246.    
  247.  
  248. feature {NONE}
  249.    
  250.    initialize is
  251.       deferred
  252.       end;
  253.    
  254. feature 
  255.    
  256.    has_result: BOOLEAN is
  257.       do
  258.      Result := result_type /= Void;
  259.       end;
  260.    
  261.    arg_count: INTEGER is
  262.       do
  263.      if arguments /= Void then
  264.         Result := arguments.count;
  265.      end;
  266.       end;
  267.  
  268.    c_define is
  269.      -- Produce C code for definition.
  270.       require
  271.      run_class.at_run_time;
  272.      cpp.on_c
  273.       deferred
  274.       ensure     
  275.      cpp.on_c
  276.       end;
  277.    
  278.    mapping_c is
  279.      -- Produce C code when current is called and when the
  280.      -- concrete type of target is unique (`cpp' is in charge
  281.      -- of the context).
  282.       require
  283.      run_class.at_run_time;
  284.      cpp.on_c
  285.       deferred
  286.       ensure     
  287.      cpp.on_c
  288.       end;
  289.  
  290.    frozen id: INTEGER is
  291.       do
  292.      Result := current_type.id;
  293.       end;
  294.    
  295.    mapping_name is
  296.       do
  297.      cpp.put_character('r');
  298.      cpp.put_integer(id);
  299.      cpp.put_string(name.to_key);
  300.       end;
  301.  
  302. feature {ADDRESS_OF_POOL}
  303.  
  304.    address_of_c_define(caller: ADDRESS_OF) is
  305.      -- Corresponding `caller' is used for error messages.
  306.       require
  307.      caller /= Void
  308.       deferred
  309.       end;
  310.  
  311. feature {ADDRESS_OF}
  312.    
  313.    address_of_c_mapping is
  314.      -- Produce C code for operator $<feature_name>
  315.       require
  316.      run_class.at_run_time;
  317.      cpp.on_c
  318.       deferred
  319.       ensure     
  320.      cpp.on_c
  321.       end;
  322.  
  323. feature {NONE}
  324.    
  325.    address_of_wrapper_name_in(str: STRING) is
  326.       do
  327.      str.extend('W');
  328.      id.append_in(str);
  329.      str.append(name.to_key);
  330.       end;
  331.  
  332.    address_of_c_define_wrapper(caller: ADDRESS_OF) is
  333.       require
  334.      cpp.on_c
  335.       do
  336.      c_code.clear;
  337.      if result_type = Void then
  338.         c_code.append(fz_void);
  339.      else
  340.         result_type.c_type_for_external_in(c_code);
  341.      end;
  342.      c_code.extend(' ');
  343.      address_of_wrapper_name_in(c_code);
  344.      c_code.extend('(');
  345.      current_type.c_type_for_external_in(c_code);
  346.      c_code.extend(' ');
  347.      c_code.extend('C');
  348.      if arguments /= Void then
  349.         c_code.extend(',');
  350.         arguments.external_prototype_in(c_code);
  351.      end;
  352.      c_code.extend(')');
  353.      cpp.put_c_heading(c_code);
  354.      cecil_pool.define_body_of(Current);
  355.       end;
  356.  
  357.    address_of_c_mapping_wrapper is
  358.       do
  359.      c_code.clear;
  360.      address_of_wrapper_name_in(c_code);
  361.      cpp.put_string(c_code);
  362.       end;
  363.  
  364. feature {EXPRESSION} 
  365.    
  366.    is_static: BOOLEAN is 
  367.       require
  368.      small_eiffel.is_ready
  369.       deferred
  370.       end;
  371.  
  372.    static_value_mem: INTEGER is 
  373.       require
  374.      is_static;
  375.       deferred
  376.       end;
  377.  
  378. feature {CALL_PROC_CALL, E_PRECURSOR}
  379.    
  380.    collect_c_tmp is
  381.       deferred
  382.       end;
  383.    
  384. feature {C_PRETTY_PRINTER}
  385.  
  386.    put_tag is
  387.       require
  388.      run_control.no_check
  389.       local
  390.      fn: FEATURE_NAME;
  391.       do
  392.      cpp.put_character('%"');    
  393.      fn := base_feature.first_name;
  394.      fn.put_cpp_tag;
  395.      cpp.put_string(fn.to_string);
  396.      cpp.put_string(" of ");
  397.      cpp.put_string(base_feature.base_class_name.to_string);
  398.      cpp.put_character('%"');
  399.       end;
  400.  
  401. feature {NONE} -- To build the c_frame_descriptor :
  402.  
  403.    c_frame_descriptor_name_in(str: STRING) is
  404.       do
  405.      str.extend('f');
  406.      id.append_in(str);
  407.      name.mapping_c_in(str);
  408.       end;
  409.  
  410.    c_frame_descriptor is
  411.       do
  412.      if run_control.no_check then
  413.         c_code.copy("se_frame_descriptor ");
  414.         c_frame_descriptor_name_in(c_code);
  415.         cpp.put_extern7(c_code);
  416.         cpp.put_character('{');
  417.         put_tag;
  418.         c_code.clear;
  419.         c_code.extend(',');
  420.         if use_current then
  421.            c_code.extend('1');
  422.         else 
  423.            c_code.extend('0');
  424.         end;
  425.         c_code.extend(',');
  426.         c_frame_descriptor_local_count.append_in(c_code);
  427.         c_code.extend(',');
  428.         c_code.append(c_frame_descriptor_format);
  429.         c_code.append("%",1};%N");
  430.         cpp.put_string(c_code);
  431.      end;
  432.       end;
  433.  
  434. feature {E_RETRY,ASSERTION_LIST}
  435.  
  436.    c_assertion_flag is
  437.       do
  438.      c_code.clear;
  439.      c_frame_descriptor_name_in(c_code);
  440.      c_code.append(".assertion_flag");
  441.      cpp.put_string(c_code);
  442.       end;
  443.    
  444. feature {NONE} -- Tools for `compile_to_c' :
  445.  
  446.    define_prototype is
  447.       require
  448.      run_class.at_run_time;
  449.      cpp.on_c
  450.       local
  451.      mem_id: INTEGER;
  452.      no_check: BOOLEAN;
  453.       do
  454.      no_check := run_control.no_check;
  455.      if run_control.no_check then
  456.         c_frame_descriptor_local_count.reset;
  457.         c_frame_descriptor_format.clear;
  458.         c_frame_descriptor_format.extend('%"');
  459.         c_frame_descriptor_locals.clear;
  460.      end;
  461.      mem_id := id;
  462.      -- Define heading of corresponding C function.
  463.      c_code.clear;
  464.      if result_type = Void then
  465.         c_code.append(fz_void);
  466.      else
  467.         result_type.run_type.c_type_for_result_in(c_code);
  468.      end;
  469.      c_code.extend(' ');
  470.      c_code.extend('r');
  471.      mem_id.append_in(c_code);
  472.      name.mapping_c_in(c_code);
  473.      c_code.extend('(');
  474.      if no_check then
  475.         c_code.append("se_dump_stack*caller");
  476.         if use_current or else arguments /= Void then
  477.            c_code.extend(',');
  478.         end;
  479.      end;
  480.      if use_current then
  481.         current_type.c_type_for_target_in(c_code);
  482.         c_code.extend(' ');
  483.         c_code.extend('C');
  484.         current_type.c_frame_descriptor;
  485.         if arguments /= Void then
  486.            c_code.extend(',');
  487.         end;
  488.      end;
  489.      if arguments = Void then
  490.         if no_check then
  491.         elseif not use_current then
  492.            c_code.append(fz_void);
  493.         end;
  494.      else
  495.         arguments.compile_to_c_in(c_code);
  496.      end;
  497.      c_code.extend(')');
  498.      cpp.put_c_heading(c_code);
  499.      cpp.swap_on_c;
  500.       ensure     
  501.      cpp.on_c
  502.       end;
  503.    
  504.    c_define_opening is
  505.      -- Define opening section in C function.
  506.       local
  507.      t: TYPE;
  508.       do
  509.      -- (0) --------------------------- Exception handling :
  510.      if rescue_compound /= Void then
  511.         cpp.put_string("struct rescue_context rc;%N");
  512.      end;
  513.      -- (1) -------------------- Local variable for Result :
  514.      if is_once_function then
  515.         if run_control.no_check then
  516.            t := result_type.run_type;
  517.            c_frame_descriptor_locals.append("(void**)&");
  518.            once_result_in(c_frame_descriptor_locals);
  519.            c_frame_descriptor_locals.extend(',');
  520.            c_frame_descriptor_local_count.increment;
  521.            c_frame_descriptor_format.append(us_result);
  522.            t.c_frame_descriptor;
  523.         end;
  524.      elseif result_type /= Void then
  525.         t := result_type.run_type;
  526.         c_code.clear;
  527.         t.c_type_for_result_in(c_code);
  528.         c_code.append(" R=");
  529.         t.c_initialize_in(c_code);
  530.         c_code.append(fz_00);
  531.         cpp.put_string(c_code);
  532.         if run_control.no_check then
  533.            c_frame_descriptor_locals.append("(void**)&R,");
  534.            c_frame_descriptor_local_count.increment;
  535.            c_frame_descriptor_format.append(us_result);
  536.            t.c_frame_descriptor;
  537.         end;
  538.      end;
  539.      -- (2) ----------------------- User's local variables :
  540.      if local_vars /= Void then
  541.         local_vars.c_declare;
  542.      end;
  543.      -- (3) ---------------- Local variable for old/ensure :
  544.      if run_control.ensure_check then
  545.         if ensure_assertion /= Void then
  546.            ensure_assertion.c_declare_for_old;
  547.         end;
  548.      end;
  549.      if run_control.no_check then
  550.      -- (4) ------------------------------- Prepare locals :
  551.         if c_frame_descriptor_local_count.value > 0 then
  552.            c_code.copy("void**locals[");
  553.            c_frame_descriptor_local_count.append_in(c_code);
  554.            c_code.extend(']');
  555.            c_code.append(fz_00);
  556.            cpp.put_string(c_code);
  557.         end;
  558.      -- (5) ----------------------------------- Prepare ds :
  559.         c_initialize_ds_one_by_one;
  560.         c_initialize_locals_one_by_one;
  561.      -- (6) ------------------------ Initialise Dump Stack :
  562.         cpp.put_string("se_dst=&ds;/*link*/%N");
  563.      end;
  564.      -- (7) ----------------------- Execute old for ensure :
  565.      if run_control.ensure_check then
  566.         if ensure_assertion /= Void then
  567.            ensure_assertion.compile_to_c_old;
  568.         end;
  569.      end;
  570.      -- (8) --------------------------- Exception handling :
  571.      if rescue_compound /= Void then
  572.         cpp.put_string("if(SETJMP(rc.jb)!=0){/*rescue*/%N");
  573.         if run_control.no_check then
  574.            cpp.put_string(
  575.                   "while(se_dst!=&ds){%N%
  576.               %if(se_dst->fd!=NULL)se_dst->fd->assertion_flag=1;%N%
  577.               %se_dst = se_dst->caller;%N}%N");
  578.         end;
  579.         rescue_compound.compile_to_c;
  580.         cpp.put_string("internal_exception_handler(Routine_failure);%N}%N");
  581.      end;
  582.      -- (9) -------------------- Initialize local expanded :
  583.      if local_vars /= Void then
  584.         local_vars.initialize_expanded;
  585.      end;
  586.      -- (10) --------------------------- Retry start label :
  587.      if rescue_compound /= Void then
  588.         cpp.put_string("retry_tag:%N");
  589.      end;
  590.      -- (11) ---------------------- Require assertion code :
  591.      if require_assertion /= Void then
  592.         require_assertion.compile_to_c;
  593.      end;
  594.      -- (12) ------------------------- Save rescue context :
  595.      if rescue_compound /= Void then
  596.         cpp.put_string("rc.next = rescue_context_top;%N%
  597.                %rescue_context_top = &rc;%N");
  598.         if run_control.no_check then
  599.            cpp.put_string("se_dst=&ds;/*link*/%N");
  600.         end;
  601.      end;
  602.       end;
  603.    
  604.    c_define_closing is
  605.      -- Define closing section in C function :
  606.      --    - code for ensure checking.
  607.      --    - free memory of expanded.
  608.      --    - run stack pop.
  609.       do
  610.      -- (1) --------------------------- Ensure Check Code :
  611.      if run_control.ensure_check then
  612.         if ensure_assertion /= Void then
  613.            ensure_assertion.compile_to_c;
  614.         end;
  615.      end;
  616.      -- (2) ----------------------------- Class Invariant :
  617.      if use_current then
  618.         cpp.current_class_invariant(current_type);
  619.      end;
  620.      -- (3) ---------------------------------- For rescue :
  621.      if rescue_compound /= Void then
  622.         cpp.put_string("rescue_context_top = rc.next;%N");
  623.      end;
  624.      -- (4) ------------------------------- Run Stack Pop :
  625.      if run_control.no_check then
  626.         cpp.put_string("se_dst=caller;/*unlink*/%N");
  627.      end;
  628.       end;
  629.    
  630. feature {NONE}
  631.  
  632.    external_prototype(er: EXTERNAL_ROUTINE) is
  633.      -- Define prototype for an external routine.
  634.       require
  635.      cpp.on_c;
  636.      er = base_feature
  637.       local
  638.      t: TYPE;
  639.       do
  640.      c_code.clear;
  641.      c_code.append("/*external*/");
  642.      -- Define heading of corresponding C function.
  643.      t := result_type;
  644.      if t = Void then
  645.         c_code.append(fz_void);
  646.      else
  647.         t.c_type_for_external_in(c_code);
  648.      end;
  649.      c_code.extend(' ');
  650.      c_code.append(er.external_c_name);
  651.      c_code.extend('(');
  652.      if er.use_current then
  653.         current_type.c_type_for_external_in(c_code);
  654.         c_code.extend(' ');
  655.         c_code.extend('C');
  656.         if arguments /= Void then
  657.            c_code.extend(',');
  658.         end;
  659.      end;
  660.      if arguments = Void then
  661.         if not er.use_current then
  662.            c_code.append(fz_void);
  663.         end;
  664.      else
  665.         arguments.external_prototype_in(c_code);
  666.      end;
  667.      c_code.append(");%N");
  668.      cpp.swap_on_h;
  669.      cpp.put_string(c_code);
  670.      cpp.swap_on_c;
  671.       ensure     
  672.      cpp.on_c
  673.       end;
  674.  
  675. feature {NONE}
  676.  
  677.    once_mark: STRING is
  678.       do
  679.      Result := base_feature.first_name.to_string;
  680.       end;
  681.  
  682.    once_flag_in(str: STRING) is
  683.      -- Produce the C name of the once flag.
  684.       do
  685.      str.extend('f');
  686.      base_feature.mapping_c_name_in(str);
  687.       end;
  688.    
  689.    once_flag is
  690.      -- Produce the C name of the once flag.
  691.       do
  692.      c_code.clear;
  693.      once_flag_in(c_code);
  694.      cpp.put_string(c_code);
  695.       end;
  696.    
  697.    once_boolean is
  698.      -- Produce C code for the boolean flag definition
  699.      -- and initialisation.
  700.       do
  701.      c_code.copy(fz_int);
  702.      c_code.extend(' ');
  703.      once_flag_in(c_code);
  704.      cpp.put_extern2(c_code,'0');
  705.       end;
  706.    
  707. feature {NONE}
  708.  
  709.    use_current_state: INTEGER;
  710.    
  711.    ucs_false,
  712.    ucs_true, 
  713.    ucs_not_computed, 
  714.    ucs_in_computation: INTEGER is unique;
  715.       
  716.    std_compute_use_current is
  717.       require
  718.      use_current_state = ucs_in_computation;
  719.       do
  720.      if use_current_state = ucs_in_computation then
  721.         if require_assertion /= Void then
  722.            if require_assertion.use_current then
  723.           use_current_state := ucs_true;
  724.            end;
  725.         end;
  726.      end;
  727.      if use_current_state = ucs_in_computation then
  728.         if routine_body /= Void then
  729.            if routine_body.use_current then
  730.           use_current_state := ucs_true;
  731.            end;
  732.         end;        
  733.      end;
  734.       if use_current_state = ucs_in_computation then
  735.         if rescue_compound /= Void then
  736.            if rescue_compound.use_current then
  737.           use_current_state := ucs_true;
  738.            end;
  739.         end;        
  740.      end;
  741.      if use_current_state = ucs_in_computation then
  742.         if ensure_assertion /= Void then
  743.            if ensure_assertion.use_current then
  744.           use_current_state := ucs_true;
  745.            end;
  746.         end;        
  747.      end;
  748.      if use_current_state = ucs_in_computation then
  749.         use_current_state := ucs_false;
  750.      end;
  751.       ensure
  752.      use_current_state = ucs_false or else
  753.      use_current_state = ucs_true;     
  754.       end;
  755.    
  756.    compute_use_current is 
  757.       require
  758.      use_current_state = ucs_in_computation;
  759.       deferred 
  760.       ensure
  761.      use_current_state = ucs_true or else
  762.      use_current_state = ucs_false;
  763.       end;
  764.  
  765. feature {NONE}
  766.  
  767.    c_code, c_code2: STRING is
  768.             "................................................................%
  769.             %................................................................%
  770.         %................................................................%
  771.         %................................................................";
  772.  
  773. feature {NATIVE}
  774.    
  775.    frozen default_mapping_procedure is
  776.      -- Default mapping for procedure calls with target.
  777.       do
  778.      default_mapping_function;
  779.      cpp.put_string(fz_00);
  780.       end;
  781.  
  782.    frozen default_mapping_function is
  783.      -- Default mapping for function calls with target.
  784.       local
  785.      no_check, uc, tcbd: BOOLEAN;
  786.       do
  787.      no_check := run_control.no_check;
  788.      uc := use_current;
  789.      if not uc then
  790.         tcbd := cpp.target_cannot_be_dropped;
  791.         if tcbd then
  792.            cpp.put_character(',');
  793.         end;
  794.      end;
  795.      mapping_name;
  796.      cpp.put_character('(');
  797.      if no_check then
  798.         cpp.put_string("&ds");
  799.      end;
  800.      if uc then 
  801.         if no_check then
  802.            cpp.put_character(',');
  803.         end;
  804.         cpp.put_target_as_target;
  805.      end;
  806.      if arguments /= Void then
  807.         if uc or else no_check then
  808.            cpp.put_character(',');
  809.         end;
  810.         cpp.put_arguments;
  811.      end;
  812.      cpp.put_character(')');
  813.      if not uc and then tcbd then
  814.         cpp.put_character(')');
  815.      end;
  816.       end;
  817.  
  818. feature {NONE}
  819.  
  820.    nothing_comment is
  821.      -- Useful for incremental recompilation.
  822.       do
  823.      cpp.put_string(fz_open_c_comment);
  824.      cpp.put_string("No:");
  825.      cpp.put_string(current_type.run_time_mark);
  826.      cpp.put_character('.');
  827.      cpp.put_string(name.to_string);
  828.      cpp.put_string(fz_close_c_comment);
  829.      cpp.put_character('%N');
  830.       end;
  831.  
  832. feature {NATIVE}
  833.  
  834.    routine_mapping_jvm is
  835.       local
  836.      rt, ct: TYPE;
  837.      idx, stack_level: INTEGER;
  838.       do
  839.      ct := current_type;
  840.      jvm.push_target_as_target;
  841.      stack_level := -(1 + jvm.push_arguments);
  842.      rt := result_type;
  843.      if rt /= Void then
  844.         stack_level := stack_level + rt.jvm_stack_space;
  845.      end
  846.      idx := constant_pool.idx_methodref(Current);
  847.      ct.run_class.jvm_invoke(idx,stack_level);
  848.       end;
  849.       
  850. feature {RUN_CLASS}
  851.    
  852.    jvm_field_or_method is
  853.      -- Update jvm's `fields' or `methods' if needed.
  854.       deferred
  855.       end;
  856.  
  857. feature 
  858.  
  859.    mapping_jvm is
  860.       require
  861.      run_class.at_run_time
  862.       deferred
  863.       end;
  864.  
  865. feature {JVM}
  866.  
  867.    jvm_define is
  868.      -- To compute the constant pool, the number of fields,
  869.      -- the number of methods, etc.
  870.       require
  871.      small_eiffel.is_ready
  872.       deferred
  873.       end;
  874.  
  875. feature {CONSTANT_POOL,SWITCH_COLLECTION}
  876.  
  877.    frozen jvm_descriptor: STRING is
  878.       do
  879.      tmp_jvm_descriptor.clear;
  880.      update_tmp_jvm_descriptor;
  881.      Result := tmp_jvm_descriptor;
  882.       end;
  883.  
  884. feature {NONE}
  885.  
  886.    update_tmp_jvm_descriptor is
  887.       deferred
  888.       end;
  889.  
  890.    tmp_jvm_descriptor: STRING is
  891.       once
  892.      !!Result.make(128);
  893.       end;
  894.  
  895.    routine_update_tmp_jvm_descriptor is
  896.      -- For RUN_FEATURE_3/4/5/6/7/8/9/10/11 :
  897.       local
  898.      ct, rt: TYPE;
  899.       do
  900.      tmp_jvm_descriptor.extend('(');
  901.      ct := current_type;
  902.      ct.jvm_target_descriptor_in(tmp_jvm_descriptor);
  903.      if arguments /= Void then
  904.         arguments.jvm_descriptor_in(tmp_jvm_descriptor);
  905.      end;
  906.      rt := result_type;
  907.      if rt = Void then
  908.         tmp_jvm_descriptor.append(fz_19);
  909.      else
  910.         rt := rt.run_type;
  911.         tmp_jvm_descriptor.extend(')');
  912.         rt.jvm_descriptor_in(tmp_jvm_descriptor);
  913.      end;
  914.       end;
  915.  
  916. feature {NONE}
  917.  
  918.    method_info_start is
  919.       local
  920.      flags: INTEGER;
  921.       do
  922.      flags := current_type.jvm_method_flags;
  923.      method_info.start(flags,name.to_key,jvm_descriptor);
  924.       end;
  925.  
  926.    jvm_define_opening is
  927.       require
  928.      jvm.current_frame = Current
  929.       local
  930.      t: TYPE;
  931.       do
  932.      -- (1) -------------------- Local variable for Result :
  933.      if result_type /= Void then
  934.         t := result_type.run_type;
  935.         t.jvm_initialize_local(jvm_result_offset);
  936.      end;
  937.      -- (2) ----------------------- User's local variables :
  938.      if local_vars /= Void then
  939.         local_vars.jvm_initialize;
  940.      end;
  941.      -- (3) ---------------- Local variable for old/ensure :
  942.      if run_control.ensure_check then
  943.         if ensure_assertion /= Void then
  944.            ensure_assertion.compile_to_jvm_old;
  945.         end;
  946.      end;
  947.      -- (4) ----------------------- Require assertion code :
  948.      if require_assertion /= Void then
  949.         require_assertion.compile_to_jvm;
  950.      end;
  951.       end;
  952.  
  953.    jvm_define_closing is
  954.       require
  955.      jvm.current_frame = Current
  956.       do
  957.      -- (0) ----------------------------- Class Invariant :
  958.      -- (1) --------------------------- Ensure Check Code :
  959.      if run_control.ensure_check then
  960.          if ensure_assertion /= Void then
  961.            ensure_assertion.compile_to_jvm(true);
  962.            code_attribute.opcode_pop;
  963.          end;
  964.      end;
  965.      -- (2) --------------------- Free for local expanded :
  966.      -- (3) ------------------- Prepare result for return :
  967.      if result_type /= Void then
  968.         result_type.jvm_push_local(jvm_result_offset);
  969.      end;
  970.       end;
  971.  
  972. feature {JVM}
  973.  
  974.    frozen jvm_result_offset: INTEGER is
  975.       require
  976.      result_type /= Void
  977.       do
  978.      Result := current_type.jvm_stack_space;
  979.      if arguments /= Void then
  980.         Result := Result + arguments.jvm_stack_space;
  981.      end;
  982.      if local_vars /= Void then
  983.         Result := Result + local_vars.jvm_stack_space;
  984.      end;
  985.       end;
  986.  
  987.    frozen jvm_argument_offset(a: ARGUMENT_NAME): INTEGER is
  988.       require
  989.      arguments /= Void
  990.       do
  991.      Result := current_type.jvm_stack_space;
  992.      Result := Result + arguments.jvm_offset_of(a);
  993.       ensure
  994.      Result >= a.rank - 1
  995.       end;
  996.  
  997.    frozen jvm_local_variable_offset(ln: LOCAL_NAME): INTEGER is
  998.       require
  999.      local_vars /= Void
  1000.       do
  1001.      Result := current_type.jvm_stack_space;
  1002.      if arguments /= Void then
  1003.         Result := Result + arguments.jvm_stack_space;
  1004.      end;
  1005.      Result := Result + local_vars.jvm_offset_of(ln);
  1006.       ensure
  1007.      Result >= ln.rank - 1
  1008.       end;
  1009.  
  1010. feature 
  1011.  
  1012.    frozen jvm_max_locals: INTEGER is
  1013.       do
  1014.      Result := current_type.jvm_stack_space;
  1015.      if arguments /= Void then
  1016.         Result := Result + arguments.jvm_stack_space;
  1017.      end;
  1018.      if local_vars /= Void then
  1019.         Result := Result + local_vars.jvm_stack_space;
  1020.      end;
  1021.      if result_type /= Void then
  1022.         Result := Result + result_type.jvm_stack_space;
  1023.      end;
  1024.       end;
  1025.  
  1026. feature {NONE}
  1027.  
  1028.    routine_afd_check is
  1029.       do
  1030.      if require_assertion /= Void then
  1031.         require_assertion.afd_check;
  1032.      end;
  1033.      if routine_body /= Void then
  1034.         routine_body.afd_check;
  1035.      end;
  1036.      if rescue_compound /= Void then
  1037.         rescue_compound.afd_check;
  1038.       end;
  1039.      if ensure_assertion /= Void then
  1040.         ensure_assertion.afd_check;
  1041.      end;
  1042.       end;
  1043.  
  1044. feature {NONE}
  1045.  
  1046.    c_initialize_ds_one_by_one is
  1047.       require
  1048.      run_control.no_check
  1049.       do
  1050.      c_code.copy("se_dump_stack ds;%Nds.fd=&");
  1051.      c_frame_descriptor_name_in(c_code);
  1052.      c_code.append(fz_00);
  1053.      if use_current then
  1054.         c_code.append("ds.current=((void**)&C);%N");
  1055.      else
  1056.         c_code.append("ds.current=NULL;%N");
  1057.      end;
  1058.      cpp.put_string(c_code);
  1059.      cpp.put_position_in_ds(start_position);
  1060.      cpp.put_string("ds.caller=caller;%N");
  1061.      if c_frame_descriptor_local_count.value > 0 then
  1062.         cpp.put_string("ds.locals=locals;%N");
  1063.      end;
  1064.       end;
  1065.  
  1066.    c_initialize_locals_one_by_one is
  1067.       require
  1068.      run_control.no_check
  1069.       local
  1070.      i, j: INTEGER;
  1071.      c: CHARACTER;
  1072.       do
  1073.      from
  1074.         j := 1;
  1075.      until
  1076.         c_frame_descriptor_local_count.value = i
  1077.      loop
  1078.         cpp.put_string("locals[");
  1079.         cpp.put_integer(i);
  1080.         cpp.put_string("]=");
  1081.         from
  1082.            c := c_frame_descriptor_locals.item(j); 
  1083.         until
  1084.            c = ','
  1085.         loop
  1086.            cpp.put_character(c);
  1087.            j := j + 1;
  1088.            c := c_frame_descriptor_locals.item(j); 
  1089.         end;
  1090.         j := j + 1;
  1091.         cpp.put_string(fz_00);
  1092.         i := i + 1;
  1093.      end;
  1094.       end;
  1095.  
  1096. feature {NATIVE}
  1097.  
  1098.    frozen c_define_with_body(body: STRING) is
  1099.       require
  1100.      body /= Void
  1101.       do
  1102.      define_prototype;
  1103.      c_define_opening;
  1104.      cpp.put_string(body);
  1105.      c_define_closing;
  1106.      if result_type = Void then
  1107.         cpp.put_string(fz_12);
  1108.      else
  1109.         cpp.put_string(fz_15);
  1110.      end;
  1111.      c_frame_descriptor;
  1112.       end;
  1113.  
  1114. feature {ONCE_ROUTINE_POOL}   
  1115.  
  1116.    frozen once_result_in(str: STRING) is
  1117.      -- Produce the C name of the once Result.
  1118.       require
  1119.      is_once_function
  1120.       do
  1121.      str.extend('o');
  1122.      base_feature.mapping_c_name_in(str);
  1123.       end;
  1124.    
  1125. invariant
  1126.    
  1127.    current_type /= Void;
  1128.    
  1129.    name /= Void;
  1130.    
  1131.    base_feature /= Void;
  1132.    
  1133. end -- RUN_FEATURE
  1134.  
  1135.